﻿using System;
using System.Data;
using System.Data.SqlClient;
using System.Reflection;
using System.Collections.Specialized;
using DataAccess;
using DataAccess.Attributes;
using System.Data.Odbc;
using DataAccess.ODBC;


namespace DataAccess.ODBC
{
    /// <summary>
    /// 涴跺濬釬峈垀衄杅擂湔郪璃腔價濬ㄛ俇傖杅擂湔腔價掛紱釬
    /// 衄壽腔杅擂踱溼恀摯紱釬價衾Microsoft.ApplicationBlocks.Data減膘
    /// </summary>
    public class ODBCAccess<T>: DataAccess<T> where T : class
    {
        public ODBCAccess(String strConn) : base(strConn) { }
        #region search
        /// <summary>
        /// 籵蚚腔刲坰源楊ㄛ跦擂換腔杅擂濬倰殿隙等跺妗极勤砓﹝
        /// </summary>
        /// <param name="type">刲坰腔妗极勤砓腔濬倰﹝</param>
        /// <returns>脤梑善腔妗极勤砓﹝</returns>
        protected T SearchEntity(Type type)
        {
            //鳳腕妗极勤砓腔扽俶ㄛ跦擂扽俶隅妗极勤砓勤茼腔杅擂踱笢腔桶靡備睿ID蹈靡備﹝
            //壽衾扽俶ㄛ褫眕統蕉狟蹈MSDN腔翋枙ㄩ
            //1. .NET Framework Class Library  Attribute Class  
            //2. .NET Framework Developer's Guide 	Extending Metadata Using Attributes
            EntityAttribute attribute = (EntityAttribute)(type.GetCustomAttributes(typeof(EntityAttribute), false)[0]);
            string selectTable = attribute.SelectTable;
            string identityProperty = attribute.IdentityProperty;

            T entity = null;

            OdbcParameter SelectTable = new OdbcParameter("@SourceTable", selectTable);
            OdbcParameter IdentityProperty = new OdbcParameter("@PrimaryKey", identityProperty);
            OdbcParameter FilterStr = new OdbcParameter("@WhereClause", this.filter.ToString());
            OdbcParameter SorterStr = new OdbcParameter("@OrderByClause", this.sorter.ToString());
            OdbcParameter PageIndexs = new OdbcParameter("@PageIndex", this.pageIndex);
            PageIndexs.DbType = DbType.Int32;
            OdbcParameter PageSizes = new OdbcParameter("@PageSize", this.pageSize);
            PageSizes.DbType = DbType.Int32;
            OdbcParameter RecordsCount = new OdbcParameter("@TotalCount", 1);
            RecordsCount.Direction = ParameterDirection.Output;
            RecordsCount.DbType = DbType.Int32;
            //質翑OdbcHelper堆翑濬ㄛ籵徹OdbcDataReader黍杅擂踱囀ㄛ甜沓喃妗极勤砓﹝
            //using(OdbcDataReader rdr = OdbcHelper.ExecuteReader(ConnectionString, "Search", selectTable, identityProperty, this.filter.ToString(), this.sorter.ToString(), this.pageIndex, this.pageSize, this.totalCount))
            using (OdbcDataReader rdr = OdbcHelper.ExecuteReader(ConnectionString, "Search", SelectTable, IdentityProperty, FilterStr, SorterStr, PageIndexs, PageSizes, RecordsCount))
            {
                if (rdr.Read())
                    entity = FillEntity(rdr, type.GetType(), string.Empty);
            }
            this.TotalCount = (Int32)RecordsCount.Value;
            //殿隙妗极勤砓﹝
            return entity;
        }
        public override EntityCollection<T> SearchEntityList(Type type)
        {
            System.Collections.ArrayList bb = new System.Collections.ArrayList();

            //EntityCollection<int> aa = new EntityCollection<int>();

            //鳳腕妗极勤砓腔扽俶ㄛ跦擂扽俶隅妗极勤砓勤茼腔杅擂踱笢腔桶靡備睿ID蹈靡備﹝
            //壽衾扽俶ㄛ褫眕統蕉狟蹈MSDN腔翋枙ㄩ
            //1. .NET Framework Class Library  Attribute Class  
            //2. .NET Framework Developer's Guide 	Extending Metadata Using Attributes
            EntityAttribute attribute = (EntityAttribute)(type.GetCustomAttributes(typeof(EntityAttribute), false)[0]);
            string selectTable = attribute.SelectTable;
            string identityProperty = attribute.IdentityProperty;

            EntityCollection<T> collection = new EntityCollection<T>();

            //質翑OdbcHelper堆翑濬ㄛ籵徹OdbcDataReader黍杅擂踱囀ㄛ甜沓喃妗极勤砓摩磁﹝
            OdbcParameter SelectTable = new OdbcParameter("@SourceTable", selectTable);
            OdbcParameter IdentityProperty = new OdbcParameter("@PrimaryKey", identityProperty);
            OdbcParameter FilterStr = new OdbcParameter("@WhereClause", this.filter.ToString());
            OdbcParameter SorterStr = new OdbcParameter("@OrderByClause", this.sorter.ToString());
            OdbcParameter PageIndexs = new OdbcParameter("@PageIndex", this.pageIndex);
            PageIndexs.DbType = DbType.Int32;
            OdbcParameter PageSizes = new OdbcParameter("@PageSize", this.pageSize);
            PageSizes.DbType = DbType.Int32;
            OdbcParameter RecordsCount = new OdbcParameter();
            RecordsCount.ParameterName = "@TotalCount";
            RecordsCount.Direction = ParameterDirection.Output;
            RecordsCount.DbType = DbType.Int32;

            //using(OdbcDataReader rdr = OdbcHelper.ExecuteReader(ConnectionString, "Search", selectTable, identityProperty, this.filter.ToString(), this.sorter.ToString(), this.pageIndex, this.pageSize, this.totalCount))
            using (OdbcDataReader rdr = OdbcHelper.ExecuteReader(ConnectionString, CommandType.StoredProcedure, "Search", SelectTable, IdentityProperty, FilterStr, SorterStr, PageIndexs, PageSizes, RecordsCount))
            {

                while (rdr.Read())
                {
                    T entity = FillEntity(rdr, type.GetType(), string.Empty);
                    if (entity != null)
                        collection.Add(entity);
                }
            }
            this.TotalCount = (Int32)RecordsCount.Value;
            //殿隙妗极勤砓摩磁﹝
            return collection;
        } 
   

        public override EntityCollection<T> Select(string strbusinessEntity, NameValueCollection combine, out int totalCount, int pageSize, int pageIndex)
        {
            Type type = Type.GetType(strbusinessEntity);
            foreach (string key in combine.Keys)
            {
                this.Filter.AddLike(false, key, combine[key], false);
            }

            this.PageSize = pageSize;
            this.PageIndex = pageIndex;
            EntityCollection<T> Collection = this.SearchEntityList(type);
            totalCount = this.TotalCount;
            return Collection;
        }


        /// <summary>
        /// 籵徹揣湔徹最殿隙杅擂
        /// </summary>
        /// <param name="spName">揣湔徹最靡備</param>
        /// <param name="parameterValues">統杅</param>
        /// <returns></returns>
        public DataSet SearchDataByspName(string spName, params object[] parameterValues)
        {
            DataSet ds = OdbcHelper.ExecuteDataset(ConnectionString, spName, parameterValues);

            return ds;
        }

        public OdbcDataReader SearchDataReaderByspName(string spName, params object[] parameterValues)
        {
            OdbcDataReader rdr = OdbcHelper.ExecuteReader(ConnectionString, spName, parameterValues);

            return rdr;

            //return OdbcHelper.ExecuteReader(ConnectionString, spName, parameterValues);
        }
        
        
        #endregion

        #region insert

        public override bool Insert(T[] entitys)
        {
            string strSQL = string.Empty;
            string updateTable = string.Empty;
            System.Text.StringBuilder sbNames = new System.Text.StringBuilder();
            System.Text.StringBuilder sbValues = new System.Text.StringBuilder();
            for (int i = 0; i < entitys.Length; i++)
            {
                EntityAttribute attribute = (EntityAttribute)(entitys[i].GetType().GetCustomAttributes(typeof(EntityAttribute), false)[0]);
                updateTable = attribute.UpdateTable;
                string[] identityProperty = attribute.IdentityProperty.Split(",".ToCharArray());
                sbNames.Length = 0;
                sbValues.Length = 0;
                foreach (PropertyInfo info in entitys[i].GetType().GetProperties())
                {
                    PropertyCAttribute cAttr;
                    if (info.GetCustomAttributes(typeof(PropertyCAttribute), false).Length > 0)
                    {
                        cAttr = (PropertyCAttribute)(info.GetCustomAttributes(typeof(PropertyCAttribute), false)[0]);
                        //不是關鍵字段，或者不自動生成
                        if (!cAttr.IsPrimaryKey || !cAttr.Autogenerate)
                        {
                            sbNames.Append(info.Name + ",");
                            sbValues.Append(string.Format("'{0}',", info.GetValue(entitys[i], null)));
                        }
                    }
                    else
                    {
                        sbNames.Append(info.Name + ",");
                        sbValues.Append(string.Format("'{0}',", info.GetValue(entitys[i], null)));
                    }

                }
                sbNames.Remove(sbNames.Length - 1, 1);
                sbValues.Remove(sbValues.Length - 1, 1);
                strSQL += string.Format("INSERT INTO {0}({1}) VALUES({2}) ", updateTable, sbNames.ToString(), sbValues.ToString());
            }
            try
            {
                if (strSQL != string.Empty)
                    OdbcHelper.ExecuteNonQuery(ConnectionString, CommandType.Text, strSQL);
            }
            catch (Exception ex)
            {
                throw new Exception(string.Format("插入{0}表失敗：{1}", updateTable, ex.Message.Replace("'", "\'").Replace("\\", "\\\\")));
            }
            return true;
        }

        /// <summary>
        /// 蔚妗极勤砓脣杅擂踱
        /// </summary>
        /// <param name="entity">妗极勤砓</param>
        /// <returns>脣傖髡殿隙trueㄛ瘁寀殿隙false</returns>
        public override bool Insert(T entity)
        {
            EntityAttribute attribute = (EntityAttribute)(entity.GetType().GetCustomAttributes(typeof(EntityAttribute), false)[0]);
            string updateTable = attribute.UpdateTable;
            string[] identityProperty = attribute.IdentityProperty.Split(",".ToCharArray());
            System.Text.StringBuilder sbNames = new System.Text.StringBuilder();
            System.Text.StringBuilder sbValues = new System.Text.StringBuilder();
            foreach (PropertyInfo info in entity.GetType().GetProperties())
            {
                PropertyCAttribute cAttr;
                if (info.GetCustomAttributes(typeof(PropertyCAttribute), false).Length > 0)
                {
                    cAttr = (PropertyCAttribute)(info.GetCustomAttributes(typeof(PropertyCAttribute), false)[0]);
                    //不是關鍵字段，或者不自動生成
                    if (!cAttr.IsPrimaryKey || !cAttr.Autogenerate)
                    {
                        sbNames.Append(info.Name + ",");
                        sbValues.Append(string.Format("'{0}',", info.GetValue(entity, null)));
                    }
                }
                else
                {
                    sbNames.Append(info.Name + ",");
                    sbValues.Append(string.Format("'{0}',", info.GetValue(entity, null)));
                }
            }
            sbNames.Remove(sbNames.Length - 1, 1);
            sbValues.Remove(sbValues.Length - 1, 1);
            string strSQL = string.Format("INSERT INTO {0}({1}) VALUES({2})", updateTable, sbNames.ToString(), sbValues.ToString());
            try
            {
                OdbcHelper.ExecuteNonQuery(ConnectionString, CommandType.Text, strSQL);
            }
            catch (Exception ex)
            {
                throw new Exception(string.Format("插入{0}表失敗：{1}", updateTable, ex.Message.Replace("'", "\'").Replace("\\", "\\\\")));
            }
            return true;
        }
        /// <summary>
        /// 蔚妗极勤砓脣杅擂踱
        /// </summary>
        /// <param name="entity">妗极勤砓</param>
        /// <returns>脣傖髡殿隙trueㄛ瘁寀殿隙false</returns>
        public override bool InsertBySp(T entity)
        {
            EntityAttribute attribute = (EntityAttribute)(entity.GetType().GetCustomAttributes(typeof(EntityAttribute), false)[0]);
            string updateTable = attribute.UpdateTable;
            string identityProperty = attribute.IdentityProperty;
            string procedureName = updateTable + "_INSERT";

            int identityValue = (int)entity.GetType().GetProperty(identityProperty).GetValue(entity, null);

            if (identityValue <= 0)
            {
                OdbcParameter[] parameters = PrepareParameters(procedureName, entity);
                OdbcHelper.ExecuteNonQuery(ConnectionString, CommandType.StoredProcedure, procedureName, parameters);
                //The return value should be the scope_identity()
                for (int i = 0; i < parameters.Length; i++)
                    if (parameters[i].Direction == ParameterDirection.ReturnValue)
                        entity.GetType().GetProperty(identityProperty).SetValue(entity, (int)parameters[i].Value, null);
                return true;
            }

            return false;
        }

        
        #endregion

        #region update
        /// <summary>
        /// 蔚妗极勤砓載陔善杅擂踱
        /// </summary>
        /// <param name="entity">妗极勤砓</param>
        /// <returns>脣傖髡殿隙trueㄛ瘁寀殿隙false</returns>
        public override bool Update(T entity)
        {
            EntityAttribute attribute = (EntityAttribute)(entity.GetType().GetCustomAttributes(typeof(EntityAttribute), false)[0]);
            string updateTable = attribute.UpdateTable;
            string identityProperty = attribute.IdentityProperty;
            System.Text.StringBuilder sbUpt = new System.Text.StringBuilder();
            System.Text.StringBuilder sbCondition = new System.Text.StringBuilder();
            foreach (PropertyInfo info in entity.GetType().GetProperties())
            {
                PropertyCAttribute cAttr;
                if (info.GetCustomAttributes(typeof(PropertyCAttribute), false).Length > 0)
                {
                    cAttr = (PropertyCAttribute)(info.GetCustomAttributes(typeof(PropertyCAttribute), false)[0]);
                    //不是關鍵字段，或者不自動生成
                    if (!cAttr.IsPrimaryKey || !cAttr.Autogenerate)
                    {
                        sbUpt.Append(string.Format("{0}='{1}',", info.Name, info.GetValue(entity, null)));
                    }
                    else
                    {
                        sbCondition.Append(string.Format("{0}='{1}' and ", info.Name, info.GetValue(entity, null)));
                    }

                }
                else
                {
                    sbCondition.Append(string.Format("{0}='{1}' and ", info.Name, info.GetValue(entity, null)));
                }
            }
            sbUpt.Remove(sbUpt.Length - 1, 1);
            sbCondition.Remove(sbCondition.Length - 4, 4);
            string strSQL = string.Format("UPDATE {0} SET {1} WHERE ({2})", updateTable, sbUpt.ToString(), sbCondition.ToString());

            try
            {
                OdbcHelper.ExecuteNonQuery(ConnectionString, CommandType.Text, strSQL);
            }
            catch (Exception ex)
            {
                throw new Exception(string.Format("更新{0}表失敗：{1}", updateTable, ex.Message.Replace("'", "\'").Replace("\\", "\\\\")));
            }
            return true;

        }
        /// <summary>
        /// 蔚妗极勤砓載陔善杅擂踱
        /// </summary>
        /// <param name="entity">妗极勤砓</param>
        /// <returns>脣傖髡殿隙trueㄛ瘁寀殿隙false</returns>
        public override bool Update(T[] entitys)
        {
            string strSQL = string.Empty;
            string updateTable = string.Empty;
            for (int i = 0; i < entitys.Length; i++)
            {
                EntityAttribute attribute = (EntityAttribute)(entitys[i].GetType().GetCustomAttributes(typeof(EntityAttribute), false)[0]);
                updateTable = attribute.UpdateTable;
                string identityProperty = attribute.IdentityProperty;
                System.Text.StringBuilder sbUpt = new System.Text.StringBuilder();
                System.Text.StringBuilder sbCondition = new System.Text.StringBuilder();
                foreach (PropertyInfo info in entitys[i].GetType().GetProperties())
                {
                    PropertyCAttribute cAttr;
                    if (info.GetCustomAttributes(typeof(PropertyCAttribute), false).Length > 0)
                    {
                        cAttr = (PropertyCAttribute)(info.GetCustomAttributes(typeof(PropertyCAttribute), false)[0]);
                        //不是關鍵字段，或者不自動生成
                        if (!cAttr.IsPrimaryKey || !cAttr.Autogenerate)
                        {
                            sbUpt.Append(string.Format("{0}='{1}',", info.Name, info.GetValue(entitys[i], null)));

                        }
                        else
                        {
                            sbCondition.Append(string.Format("{0}='{1}' and ", info.Name, info.GetValue(entitys[i], null)));
                        }
                    }
                    else
                    {
                        sbCondition.Append(string.Format("{0}='{1}' and ", info.Name, info.GetValue(entitys[i], null)));
                    }
                }
                sbUpt.Remove(sbUpt.Length - 1, 1);
                sbCondition.Remove(sbCondition.Length - 4, 4);
                strSQL += string.Format("UPDATE {0} SET {1} WHERE {2} ", updateTable, sbUpt.ToString(), sbCondition.ToString());
            }
            try
            {
                if (strSQL != string.Empty)
                    OdbcHelper.ExecuteNonQuery(ConnectionString, CommandType.Text, strSQL);
            }
            catch (Exception ex)
            {
                throw new Exception(string.Format("更新{0}表失敗：{1}", updateTable, ex.Message.Replace("'", "\'").Replace("\\", "\\\\")));
            }
            return true;

        }
        /// <summary>
        /// 蔚妗极勤砓載陔善杅擂踱
        /// </summary>
        /// <param name="entity">妗极勤砓</param>
        /// <returns>脣傖髡殿隙trueㄛ瘁寀殿隙false</returns>
        public override bool UpdateBySP(T entity)
        {
            EntityAttribute attribute = (EntityAttribute)(entity.GetType().GetCustomAttributes(typeof(EntityAttribute), false)[0]);
            string updateTable = attribute.UpdateTable;
            string identityProperty = attribute.IdentityProperty;
            string procedureName = updateTable + "_UPDATE";

            int identityValue = (int)entity.GetType().GetProperty(identityProperty).GetValue(entity, null);
            if (identityValue > 0)
            {
                OdbcParameter[] parameters = PrepareParameters(procedureName, entity);
                OdbcHelper.ExecuteNonQuery(ConnectionString, CommandType.StoredProcedure, procedureName, parameters);
                return true;
            }

            return false;
        }
        
        #endregion

        #region delete

        /// <summary>
        /// 蔚杅擂踱刉壺勤茼腔妗极
        /// </summary>
        /// <param name="entity">妗极勤砓</param>
        /// <returns>刉壺傖髡殿隙trueㄛ瘁寀殿隙false</returns>
        public override bool Delete(T entity)
        {
            EntityAttribute attribute = (EntityAttribute)(entity.GetType().GetCustomAttributes(typeof(EntityAttribute), false)[0]);
            string deleteTable = attribute.DeleteTable;
            string identityProperty = attribute.IdentityProperty;
            System.Text.StringBuilder sbDel = new System.Text.StringBuilder();

            string procedureName = deleteTable + "_DELETE";
            int identityValue = (int)entity.GetType().GetProperty(identityProperty).GetValue(entity, null);
            if (identityValue > 0)
            {
                OdbcParameter[] parameters = PrepareParameters(procedureName, entity);
                OdbcHelper.ExecuteNonQuery(ConnectionString, CommandType.StoredProcedure, procedureName, parameters);
                return true;
            }
            return false;
        }

        /// <summary>
        /// 蔚杅擂踱刉壺勤茼腔妗极
        /// </summary>
        /// <param name="entity">妗极勤砓</param>
        /// <returns>刉壺傖髡殿隙trueㄛ瘁寀殿隙false</returns>
        public override bool DeleteBySP(T entity)
        {
            EntityAttribute attribute = (EntityAttribute)(entity.GetType().GetCustomAttributes(typeof(EntityAttribute), false)[0]);
            string deleteTable = attribute.DeleteTable;
            string identityProperty = attribute.IdentityProperty;
            string procedureName = deleteTable + "_DELETE";
            int identityValue = (int)entity.GetType().GetProperty(identityProperty).GetValue(entity, null);
            if (identityValue > 0)
            {
                OdbcParameter[] parameters = PrepareParameters(procedureName, entity);
                OdbcHelper.ExecuteNonQuery(ConnectionString, CommandType.StoredProcedure, procedureName, parameters);
                return true;
            }
            return false;
        }
        
        #endregion



        #region Prepare Parameters
        /// <summary>
        /// 袧掘SQL統杅勤砓﹝
        /// </summary>
        /// <param name="procedureName">渾覃蚚腔湔揣徹最靡備</param>
        /// <param name="entity">勤茼腔妗极勤砓</param>
        /// <returns>袧掘疑腔統杅杅郪</returns>
        protected OdbcParameter[] PrepareParameters(string procedureName, T entity)
        {
            //植杅擂踱鳳腕SQL統杅腔啋杅擂﹝
            OdbcParameter[] parameters = OdbcHelperParameterCache.GetCachedParameterSet(ConnectionString, procedureName);
            if (parameters == null)
            {
                parameters = OdbcHelperParameterCache.GetSpParameterSet(ConnectionString, procedureName, true);
                OdbcHelperParameterCache.CacheParameterSet(ConnectionString, procedureName, parameters);
            }

            //蚚妗极腔杅擂袧掘SQL 統杅勤砓﹝
            Type type = entity.GetType();
            foreach (OdbcParameter para in parameters)
            {
                if (para.Direction == ParameterDirection.Input)
                {
                    object paraValue = type.GetProperty(para.ParameterName.Substring(1)).GetValue(entity, null);

                    //彆扽俶濬倰岆 'string'
                    if ((para.OdbcType == OdbcType.NChar) || (para.OdbcType == OdbcType.NVarChar) || (para.OdbcType == OdbcType.Char) || (para.OdbcType == OdbcType.VarChar))
                        para.Value = AccessConvert.Write((string)paraValue);

                        //彆扽俶濬倰岆 'datetime'
                    else if (para.OdbcType == OdbcType.DateTime)
                        para.Value = AccessConvert.Write((DateTime)paraValue);

                        //彆扽俶濬倰岆 'int', 'long','Decimal','Float'...
                    else if (para.OdbcType == OdbcType.Int)
                        para.Value = AccessConvert.Write((int)paraValue);

                    else if (para.OdbcType == OdbcType.Decimal)
                        para.Value = AccessConvert.Write((Decimal)paraValue);

                    else if (para.OdbcType == OdbcType.Double )
                        para.Value = AccessConvert.Write((Double)paraValue);

                    else
                        para.Value = paraValue;
                }
            }
            return parameters;
        }
        #endregion //Prepare Parameters	

        /// <summary>
        /// 沓喃妗极勤砓﹝
        /// </summary>
        /// <param name="rdr">眒湖羲腔DataReader勤砓﹝</param>
        /// <param name="type">郗沓喃腔妗极勤砓腔濬倰</param>
        /// <param name="prefix">蹈靡腔袟</param>
        /// <returns>殿隙沓喃疑腔妗极</returns>
        protected T FillEntity(OdbcDataReader rdr, Type type, string prefix)
        {
            if (prefix != string.Empty)
                prefix += "_";

            T entity = (T)Activator.CreateInstance(type);
            PropertyInfo[] properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public);
            foreach (PropertyInfo property in properties)
            {
                string columnName = prefix + property.Name;

                //彆扽俶岆鍚俋濬倰妗极腔摩磁
                if (property.PropertyType == typeof(EntityCollection<T>))
                    property.SetValue(entity, FillEntityCollection(entity, property), null);

                    //彆扽俶岆鍚俋濬倰腔等跺妗极
                else if (property.PropertyType.IsSubclassOf(type))
                    property.SetValue(entity, FillEntity(rdr, property.PropertyType, property.Name), null);

                    //彆濬倰岆  'string'
                else if (property.PropertyType == typeof(System.String))
                    property.SetValue(entity, AccessConvert.ToString(rdr[columnName]), null);

                    //彆濬倰岆  'datetime'
                else if (property.PropertyType == typeof(System.DateTime))
                    property.SetValue(entity, AccessConvert.ToDateTime(rdr[columnName]), null);

                    //彆濬倰岆 'int', 'long','Double','Decimal' ......
                else if (property.PropertyType == typeof(System.Int32))
                    property.SetValue(entity, AccessConvert.ToInt32(rdr[columnName]), null);

                else if (property.PropertyType == typeof(System.Int16))
                    property.SetValue(entity, AccessConvert.ToInt16(rdr[columnName]), null);

                else if (property.PropertyType == typeof(System.Double))
                    property.SetValue(entity, AccessConvert.ToDouble(rdr[columnName]), null);

                else if (property.PropertyType == typeof(System.Decimal))
                    property.SetValue(entity, AccessConvert.ToDecimal(rdr[columnName]), null);

                else if (property.PropertyType == typeof(System.Boolean))
                    property.SetValue(entity, AccessConvert.ToBoolean(rdr[columnName]), null);

                else if (property.PropertyType == typeof(System.Byte))
                    property.SetValue(entity, AccessConvert.ToByte(rdr[columnName]), null);

                else
                   
                    property.SetValue(entity, rdr[columnName], null);
            }
            return entity;
        }

        /// <summary>
        /// 沓喃妗极摩磁﹝
        /// </summary>
        /// <param name="entity">渾沓喃腔妗极﹝</param>
        /// <param name="property">妗极腔扽俶</param>
        /// <returns>汜傖腔妗极摩磁</returns>
        protected EntityCollection<T> FillEntityCollection(T entity, PropertyInfo property)
        {
            EntityCollectionAttribute attribute = (EntityCollectionAttribute)(property.GetCustomAttributes(typeof(EntityCollectionAttribute), false)[0]);

            Type elementType = attribute.ElementType;
            string foreignKey = attribute.ForeignKeyProperty;
            string referredKey = attribute.ReferredKeyProperty;
            object referredValue = entity.GetType().GetProperty(referredKey).GetValue(entity, null);

            ODBCAccess<T> accessor = new ODBCAccess<T>(ConnectionString);
            accessor.Filter.AddEqual(true, foreignKey, referredValue);
            
            return accessor.SearchEntityList(elementType);
        }
    
    }
}
